"""
base_request.py


"""
import hashlib
import time

import allure
import requests
from requests import sessions

from common.api_log import log
from common.yaml_tools import YamlTools
from config.api_conf import URL, SIGN_SECRET


class BaseRequest:
    sess = requests.session()
    @classmethod
    def send_request(cls,**kwargs):   # 统一请求入口，异常处理
        try:
            rp = cls.sess.request(**kwargs)
        except Exception as e:
            log.error(e)
        else:
            return rp


    @classmethod
    # 生成签名（直接作为私有方法集成到类中）\
    def generate_sign(cls, parametrize_json):
        # 强制校验请求参数中是否包含必要的字段
        required_fields = ['phoneNum', 'optCode']  # 声明一个列表 required_fields，其中包含生成签名必须的字段名
        for field in required_fields:  # 循环遍历：对 required_fields 中的每个字段（phoneNum 和 optCode）进行检查。
            if field not in parametrize_json['json']:  #存在性检查：判断当前字段 field 是否存在于 parametrize_json['json'] 中
                raise ValueError(f"Missing required field: {field}")  # 抛出异常：如果字段不存在，抛出 ValueError 并明确提示缺失的字段名。
        # 生成时间戳
        mytime = str(int(time.time() * 1000))
        # 动态json[timestamp]
        parametrize_json["json"]["timestamp"] = mytime
        # 按约定规则拼接字符串（phoneNum + optCode + timestamp ）
        mysign = f"{parametrize_json['json']['phoneNum']}{parametrize_json['json']['optCode']}{parametrize_json['json']['timestamp']}"
        log.info(f"签名字符串: {mysign}")  # 添加日志
        # 加密
        sign= hashlib.md5(mysign.encode()).hexdigest()
        log.info(f"生成签名: {sign}")
        # 生成签名并添加到请求体
        parametrize_json["json"]["sign"] = sign
        return parametrize_json
    @classmethod
    def execute_api_request(cls,request,parametrize):
        # request 传入yaml文件的 request部分，接口的通用信息
        # parametrize 传入的 测试用例列表
        method=request["method"]
        allure.attach(method,f"接口请求方式{method}", attachment_type=allure.attachment_type.TEXT)
        url= URL+request["url"]
        allure.attach(url, f"接口地址为{url}", attachment_type=allure.attachment_type.TEXT)
        cookies= request["cookies"]
        if cookies is not None:
            allure.attach(cookies, f"cookie信息为{cookies}", attachment_type=allure.attachment_type.TEXT)
        headers= request["headers"]
        if headers is not None:
            allure.attach(headers, f"headers信息为{headers}", attachment_type=allure.attachment_type.TEXT)
        data=parametrize["data"]
        if data is not None:
            allure.attach(str(data), f"表单参数信息为{data}", attachment_type=allure.attachment_type.TEXT)
        files= parametrize["files"]
        if files is not None:
            allure.attach(str(files), f"文件参数信息为{files}", attachment_type=allure.attachment_type.TEXT)
        params = parametrize["params"]
        if params is not None:
            allure.attach(str(params), f"查询字符串参数为{params}", attachment_type=allure.attachment_type.TEXT)
        # parametrize=cls.generate_sign(parametrize)
        json = parametrize["json"]
        if json is not None:
            allure.attach(str(json), f"json参数为{json}", attachment_type=allure.attachment_type.TEXT)
        rp = cls.send_request(method=method,url=url,cookies=cookies,headers=headers,data=data,json=json,files=files,params=params)
        # print(rp.text,rp.json())
        expect = parametrize["expect"]

        allure.attach(str(expect), f"预期结果为{expect}", attachment_type=allure.attachment_type.TEXT)
        allure.attach(rp.text, f"实际结果为{rp.text}", attachment_type=allure.attachment_type.TEXT)
        return rp









if __name__ == '__main__':
    login_yaml_data = YamlTools.read_yaml_file('api_login_data.yaml')[0]
    rp = BaseRequest.execute_api_request(request=login_yaml_data["request"],parametrize=login_yaml_data["parametrize"][0])
    re = generate_sign()
